﻿Shader "Custom/ColorAndShadow"
{
    Properties
    {
        _Color ("色调", Color) = (1,1,1,1)
        [NoScaleOffset]_MainTex ("固有色贴图", 2D) = "white" {}
        [Header(Shadow)]
        [Space]
        _GroundHeight("Ground Height", Float) = 0
		_ShadowColor("Shadow Color", Color) = (0,0,0,1)
		_ShadowFalloff("Shadow Falloff", Range(0, 1)) = 1
		_LightDir("Light Dir", Vector) = (0,0,0,0)
    }
    SubShader
    {
        Tags { "RenderType" = "Opaque" "Queue" = "Transparent+100"}
        LOD 200

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
			float4 _Color;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv) * _Color;
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);

				return col;
            }
            ENDCG
        }

        Pass
        {
			// 用使用模板测试以保证alpha显示正确
			Stencil
			{
				Ref 0
				Comp equal
				Pass incrWrap
				Fail keep
				ZFail keep
			}

			Blend SrcAlpha OneMinusSrcAlpha
			Cull Off
			ZWrite Off

			// 深度稍微偏移防止阴影与地面穿插
			Offset -1, 0

			CGPROGRAM

			#pragma vertex Vertex
			#pragma fragment Fragment

			#include "UnityCG.cginc"

			struct VertexInput
			{
				half4 vertex : POSITION;
				half3 normal : NORMAL;
			};

			struct VertexOutput
			{
				half4 vertex : SV_POSITION;
				half4 color : COLOR;
				half3 normalWS : TEXCOORD0;
			};

			half _GroundHeight;
			half4 _ShadowColor;
			half _ShadowFalloff;
			half4 _LightDir;

			inline half3 ShadowProjectPos(half4 vertPos)
			{
				half3 shadowPos;

				// 得到顶点的世界空间坐标
				half3 worldPos = mul(unity_ObjectToWorld, vertPos).xyz;

				half3 worldLightDir = _LightDir.xyz;
	
				// 阴影的世界空间坐标（低于地面的部分不做改变）
				shadowPos.y = min(worldPos.y, _GroundHeight);
				shadowPos.xz = worldPos.xz - worldLightDir.xz * max(0, worldPos.y - _GroundHeight) / worldLightDir.y;

				return shadowPos;
			}

			VertexOutput Vertex(VertexInput input)
			{
				VertexOutput output = (VertexOutput)0;

				// 得到阴影的世界空间坐标
				half3 shadowPos = ShadowProjectPos(input.vertex);

				// 转换到裁切空间
				output.vertex = mul(unity_MatrixVP, float4(shadowPos, 1.0));

				// 阴影颜色
				output.color = _ShadowColor;
				output.color.a *= _ShadowFalloff;

				return output;
			}

			half4 Fragment(VertexOutput input) : SV_Target
			{
				return input.color;
			}

			ENDCG
        }
    }
        
    FallBack "Diffuse"
}
